//
// Created by Administrator on 2022/10/23.
//

//串的基本操作
//使用线性存储结构实现串,
#include "stdio.h"
#include "string.h"
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 40
typedef int Status;
typedef char String[MAXSIZE+1]; //将String定义为char[MAXSIZE+1]类型,0位置用来存放字符串的长度
//使用数组下标为0的位置存储串的长度

//返回串S的元素个数,即串的长度
int StrLength(char* S){
    return S[0];
}


//生成一个值为字符串常量chars的串T
Status StrAssign(String T,char* P){
    if(strlen(P)>MAXSIZE){
        return ERROR;
    }
    T[0]= strlen(P);
    for (int i = 0; i < T[0]; ++i) {
        T[i+1] = *(P+i); //字符串常量的值是首字符的地址
    }
    return OK;
}
//由串S复制得到串T
Status StrCopy(const String t,String s){
    if(t==NULL){
        return ERROR;
    }else{
        s[0] = t[0];
        for (int i = 1; i <= t[0]; ++i) {
            s[i]=t[i];
        }
        return OK;
    }
}

//串存在,将串清空
Status ClearString(String s){
    s[0]=0;
    return OK;
}
//如果串为空,则返回true,否则返回false
Status StringEmpty(String s){
    if(s[0]==0){
        return TRUE;
    }else{
        return FALSE;
    }
}
//比较两个字符串的大小
int StrCompare(String s,String t){
    //首先比较两个字符串的长度
    if(s[0]!=t[0]){
        return s[0]-t[0];
    }
    //如果两个字符串长度相同,则分别去比较每个字符串
    for (int i = 1; i <= s[0]; ++i) {
        if(s[i]-t[i]!=0){
            return s[i]-t[i];
        }else{
            continue;
        }
    }
    //两个字符串相等
    return 0;

}
//用t返回由s1和s2连接成的新串
Status Concat (String t,String s1,String s2){
    if(s1[0]+s2[0]>MAXSIZE){
        return ERROR;
    }else{
        t[0] = s1[0]+s2[0];
        for (int i = 1; i <= s1[0]; ++i) {
            t[i]=s1[i];
        }
        for (int i = 1; i <= s2[0]; ++i) {
            t[s1[0]+i] = s2[i];
        }
        return OK;
    }
}

//SubString截取子串
Status SubString(String sub,String s,int pos,int len){
    //pos和len的大小要合理
    if(!(pos>0&&pos<=StrLength(s)&&len>=0&&len+pos<=StrLength(s)+1)){
        return ERROR;
    }else{
        int index = 1;
        sub[0] = len;
        for (int i = pos; i <pos+len ; ++i) {
            sub[index++] = s[i];
        }
        return OK;
    }
}
//查找子串在主串中pos字符之后第一次出现的位置
int Index(String s,String t,int pos){
    if(!(pos>0&&pos<= StrLength(s)&& StrLength(t)<= StrLength(s))){
        return ERROR;
    }else{
        int n= StrLength(s);
        int m = StrLength(t);
        int i = pos;
        String sub;
        while(i+m-1<=n){
            SubString(sub,s,i,m); //从主串s的第i个位置取t的长度给sub
            if(StrCompare(sub,t)!=0){ //如果sub和t能匹配上,那么i就是需要的值
                i++;// 否则i向后移一位
                continue;
            }else {
                return i;
            }
        }
        //说明没有匹配上
        return 0;
    }
}
//在串s的第pos个字符之前插入串t
Status StrInsert(String s,int pos,String t){
    if(!(pos>0&&pos<= StrLength(s)+1&& StrLength(s)+ StrLength(t)<=MAXSIZE)){
        return ERROR;
    }

    int m = StrLength(s);
    int n = StrLength(t);
    //将pos及后面字符向后移动
    for(int i =m;i>=pos;i--){
        s[i+n]=s[i];
    }
    //将t放入s
    for (int i = pos,j=1; i <pos+n ; ++i,j++) {
        s[i]=t[j];
    }
    s[0]=m+n;
    return OK;
}
//从pos开始删除s长度为len的子串
Status StrDelete(String s,int pos,int len ){
    if(!(pos>0&&pos<= StrLength(s)&&len>0)){
        return ERROR;
    }
    for (int i = pos; i <= StrLength(s); ++i) {
        if(i+len> StrLength(s)){
            break;
        }
        s[i] = s[i+len];
    }
    s[0] = s[0]-len;
}


//用v替代s中所有与t相等的不重叠子串,t是非空串
Status Replace (String s,String t,String v){
    if(StrLength(t)==0|| StrLength(s)==0){
        return ERROR;
    }
    int index = 1;
    int n = StrLength(t);
    int g = StrLength(v);
    do{
        index = Index(s,t,index);
        if(index!=0){ //存在要替换的字符串
            StrDelete(s,index,n);
            StrInsert(s,index,v);
            index = index+g;//开始查找剩下的字符串
        }
    }while(index);//如果查找不到字符串,直接退出
    return OK;
}

void main(){
    char* P = "goodgoogle";
    char* Q = "google";
    String p ,q,o;
    StrAssign(p,P);
    StrAssign(q,Q);
   int index =  Index(p,q,1);
    printf("%d",index);
    StrInsert(p,5,q);
    char* O = "fan";
    StrAssign(o,O);
    Replace(p,q,o);
//    StrDelete(p,5,5);
}